#include "slist.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 链表的销毁
void my_destroy(void *s)
{
    node_t *tmp = NULL;
    node_t *save = NULL;

    // 参数检查
    if (NULL == s)
    {
        perror("s not exit...");
        return;       
    }

    tmp = ((slist_t *)s)->p;

    // 销毁
    while (NULL != tmp)
    {
        // 保存
        save = tmp->next;

        // 释放
        free(tmp->data);
        tmp->data = NULL;
        free(tmp);
        tmp = NULL;

        // 指向
        tmp = save;
    }

    free(s);

    return;
}

// 创建头信息结构体
int slist_create(slist_t **s, int size, ft1 my_destroy)
{
    // 参数检查
    if (NULL == my_destroy || size <= 0)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 创建
    *s = malloc(sizeof(slist_t));
    if (NULL == *s)
    {
        perror("malloc failed...");
        goto err0;
    }
    memset(*s, 0, sizeof(slist_t));

    // 初始化
    (*s)->cnt = 0;
    (*s)->my_destroy = my_destroy;
    (*s)->p = NULL;
    (*s)->size = size;



    return 0;
err0:
    return -1;
}

// cnt++
static node_t *__node_create(slist_t *s, void *data)
{
    node_t *tmp = NULL;

    // 参数检查
    if (NULL == s || NULL == data)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 创建节点
    tmp = malloc(sizeof(node_t));
    if (NULL == tmp)
    {
        perror("malloc failed...");
        goto err0;
    }
    memset(tmp, 0, sizeof(node_t));


    // 创建data
    tmp->data = malloc(s->size);
    if (NULL == tmp->data)
    {
        perror("malloc failed...");
        goto err1;
    }
    memset(tmp->data, 0, s->size);

    s->cnt++;
    memcpy(tmp->data, data, s->size);
    tmp->next = NULL;

    return tmp;

err1:
    free(tmp);

err0:
    return NULL;
}

// 插入链表
int slist_append(slist_t *s, void *num)
{
    node_t *new_node = NULL;
    node_t *tmp = NULL;

    // 参数检查
    if (NULL == s || NULL == num)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 创建节点
    new_node = __node_create(s, num);

    tmp = s->p;

    // 插入链表
    if (NULL == tmp)
    {
        s->p = new_node;
    }
    else 
    {   
        while (NULL != tmp->next)
        {
            tmp = tmp->next;
        }
        tmp->next = new_node;
    }

    return 0;

err0:
    return -1;
}

// 链表的遍历
int slist_traverse(slist_t *s, ft1 my_printf)
{
    node_t *tmp = NULL;
    // 参数检查
    if (NULL == s || NULL == my_printf)
    {
        perror("lawless...");
        goto err0;
    }

    tmp = s->p;

    // 遍历
    while (NULL != tmp)
    {
        my_printf(tmp->data);
        tmp = tmp->next;
    }
    return 0;
err0:
    return -1;
}

int slist_prepend(slist_t *s, void *num)
{
    node_t *new_node = NULL;

    // 参数检查
    if (NULL == s || NULL == num)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 创建节点
    new_node = __node_create(s, num);

    // 头部插入链表
    new_node->next = s->p;
    s->p = new_node;

    return 0;
err0:
    return -1;
}

// 检索插入1
int slist_insert_by_index(slist_t *s, int num, int index)
{
    node_t *new_node = NULL;
    int idx = index - 1;
    int i = 0;
    node_t *tmp = NULL;


    // 参数检查
    if (NULL == s)
    {
        perror("argument lawless...");
        goto err0;
    }

    

    // 插入
    if (idx < 0)
    {
        goto err0;
    }
    else if (idx == 0)
    {
        slist_prepend(s, &num);
    }
    else if (idx >= s->cnt)
    {
        slist_append(s, &num);
    }
    else 
    {
        tmp = s->p;
        // 创建节点
        new_node = __node_create(s, &num);

        for (i = 0; i < idx - 1; i++)
        {
            tmp = tmp->next;
        }

        new_node->next = tmp->next;
        tmp->next = new_node;
    }

    return 0;
err0:
    return -1;
}

// 链表顺序插入
int slist_insert_by_order(slist_t *s, void *num)
{
    
    return 0;
}